﻿using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Xml;
using ServiceStack.Text;

namespace PersonaLibrary.ViewModel
{
	/// <summary>
	/// Not Thread safe
	/// </summary>
	internal static class PadegVm
	{
		private const string YandexUrl = "http://export.yandex.ru/inflect.xml?name=";
		private const string CacheFileName = "PadegResults.json";

		public static List<string> Sclonyat(IEnumerable<Data.Employee> employees)
		{
			ConcurrentBag<string> result = new ConcurrentBag<string>();

			ConcurrentBag<PadegItem> fileCache;
			using(FileStream file = new FileStream(CacheFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
			{
				try
				{
					fileCache = new ConcurrentBag<PadegItem>(JsonSerializer.DeserializeFromStream<PadegItem[]>(file));
				}
				catch
				{
					fileCache = new ConcurrentBag<PadegItem>();
				}
			}

			try
			{
				Parallel.ForEach(employees, employee => result.Add(Sclonyat(employee.Surname, employee.Name, employee.Patronymic, fileCache)));
			}
			catch (AggregateException)
			{
				MessageBox.Show("Не возможно просклонять, ресурс http://export.yandex.ru/inflect.xml недоступен");
				return null;
			}

			using (FileStream file = new FileStream(CacheFileName, FileMode.OpenOrCreate))
			{
				JsonSerializer.SerializeToStream(fileCache, file);
			}

			return result.ToList();
		}

		private static string Sclonyat(string surname, string name, string patromic, ConcurrentBag<PadegItem> file)
		{
			PadegItem item = file.FirstOrDefault(x => x.Original == string.Format("{0} {1} {2}", surname, name, patromic));
			if (item != null)
				return item.D;

			item = Sclonyat(string.Format("{0}{1}+{2}+{3}&format=json", YandexUrl, surname, name, patromic));

			if (string.IsNullOrEmpty(item.D))
				return item.Original;

			if (file.All(x => x.Original != item.Original))
				file.Add(item);

			return item.D;
		}

		public static PadegItem Sclonyat(string request)
		{
            HttpWebRequest client = (HttpWebRequest)WebRequest.Create(request);

            client.Proxy = WebRequest.GetSystemWebProxy();
            client.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;

			PadegItem item;

			using (WebResponse response = client.GetResponse())
			{
				DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof (PadegItem));
				item = (PadegItem) serializer.ReadObject(response.GetResponseStream());
			}

			return item;
		}
	}
}
